package com.loki
{
    import flash.events.ErrorEvent;
    import flash.events.EventDispatcher;
    import flash.external.ExternalInterface;
    
    /**
     *
     */
    [Event(name="location", type="LocationEvent")]
    
    /**
     * Javascript adapter for communicating with the Loki plugin.
     */
    public class LokiAdapter
        extends EventDispatcher
    {
        // constants
        public static const NO_STREET_ADDRESS_LOOKUP:int = 0;
        public static const LIMITED_STREET_ADDRESS_LOOKUP:int = 1;
        public static const FULL_STREET_ADDRESS_LOOKUP:int = 2;
        
        private var _id:String;
        
        /**
         * Constructor
         */
        public function LokiAdapter()
        {
            // Inserts the javascript into the page
            _id = 'loki_flex_' + Math.floor(Math.random()*1000000);
            ExternalInterface.addCallback(_id, function():void{});
            ExternalInterface.call(javascript);
            ExternalInterface.addCallback("handleSuccess", handleSuccess);
            ExternalInterface.addCallback("handleError", handleError);
            ExternalInterface.call("loki_flex.init", _id);
        }
        
        /**
         * This method initiates the scan and the actual location request. 
         * @param latlonLookup 
         * @param addressLookup
         */
        public function requestLocation(latlonLookup:Boolean, addressLookup:int):void
        {
            ExternalInterface.call("loki_flex.requestLocation", latlonLookup, addressLookup);
        }
        
        /**
         * @param key
         */
        public function setKey(key:String):void
        {
            ExternalInterface.call("loki_flex.setKey", key);
        }
        
        /**
         * @private
         */
        private function handleSuccess(location:Object):void
        {
            dispatchEvent(new LocationEvent(location));
        }
        
        /**
         * @private
         */
        private function handleError(error:int, message:String):void
        {
            dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, message));
        }
        
        // Javascript which is inserted into the page.
        static private const javascript:XML =
        <script><![CDATA[
            function()
            {
                var fileref = document.createElement("script");
                fileref.setAttribute("type", "text/javascript");
                fileref.setAttribute("src", "http://loki.com/plugin/files/loki.js");
                document.getElementsByTagName("head")[0].appendChild(fileref);
                
                loki_flex = {};
                
                loki_flex.findSwf = function(id)
                {
                    var objects = document.getElementsByTagName("object");
                    for(var i = 0; i < objects.length; i++)
                        if(typeof objects[i][id] != "undefined")
                            return objects[i];
                    
                    var embeds = document.getElementsByTagName("embed");
                    for(var j = 0; j < embeds.length; j++)
                        if(typeof embeds[j][id] != "undefined")
                            return embeds[j];
                        
                    return null;
                }
                
                loki_flex.init = function(id)
                {
                    loki_flex.swfId = id;
                    loki_flex.swf = loki_flex.findSwf(id);
                    
                    if (loki_flex.swf)
                    {
                        var interval = setInterval(function()
                        {
                            if (typeof(LokiAPI) == "function") 
                            {
                                clearInterval(interval);
                                loki_flex.createLoki();
                            }
                        }, 100);
                    }
                }
                
                loki_flex.createLoki = function()
                {
                    var handleSuccess = function(location)
                    {
                        var locationObject = loki_flex.translateLocation(location);
                        loki_flex.swf.handleSuccess(locationObject);
                    }
                    
                    var handleError = function(error, message)
                    {
                        loki_flex.swf.handleError(error, message);
                    }
                    
                    loki_flex.loki = LokiAPI();
                    loki_flex.loki.onSuccess = handleSuccess;
                    loki_flex.loki.onFailure = handleError;
                }
                
                loki_flex.setKey = function(key)
                {
                    if (loki_flex.swf)
                    {
                        loki_flex.loki.setKey(key);
                    }
                }
                
                loki_flex.requestLocation = function(latlonLookup, addressLookup)
                {
                    if (loki_flex.swf) 
                    {
                        loki_flex.loki.requestLocation(latlonLookup, addressLookup);
                    }
                }
                
                loki_flex.translateLocation = function(location)
                {
                    var obj = {};
                    obj.latitude = location.latitude;
                    obj.longitude = location.longitude;
                    obj.accuracy = location.accuracy;
                    obj.house_number = location.house_number;
                    obj.street = location.street;
                    obj.city = location.city;
                    obj.region = location.region;
                    obj.region_code = location.region_code;
                    obj.postal_code = location.postal_code;
                    obj.country = location.country;
                    obj.country_code = location.country_code;
                    obj.accuracy = location.accuracy;
                    return obj;
                }
            }
        ]]></script>;
    }
}